﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Presentation.Models;
using Caliburn.Micro;


namespace Presentation.ViewModels
{
    public class AnecdotesViewModel: PropertyChangedBase
    {
        Presentation.Interfaces.IReadModels _modelsReader;
        Presentation.Interfaces.IWriteModels _modelsWriter;

        private Anecdote _newAnecdote;

        public BindableCollection<Domain> Domains
        {
            get
            {
                return new BindableCollection<Domain>(_modelsReader.Domains); 
            }
        }

        public BindableCollection<Student> Students
        {
            get { return new BindableCollection<Student>(_modelsReader.Students); }
        }

        public BindableCollection<Anecdote> Anecdotes
        {
            get
            { 
                IOrderedEnumerable<Anecdote> sortedAnecdotes;
                sortedAnecdotes = _modelsReader.Anecdotes.OrderBy<Anecdote, string>((a) => { return a.Student.Name + a.Domain.Name + a.Date.ToString(); });

                return new BindableCollection<Anecdote>(sortedAnecdotes); ;
            }
        }

        public BindableCollection<string> UniqueNotes
        {
            get
            {
                BindableCollection<string> uniqueNotes = new BindableCollection<string>();
                foreach (Anecdote anecdote in Anecdotes)
                {
                    string note = anecdote.Note;
                    if (!uniqueNotes.Contains(note))
                    {
                        uniqueNotes.Add(note);
                    }
                }

                return uniqueNotes;
            }
        }

        public string NewAnecdoteDomain
        {
            get 
            {
                if (_newAnecdote.Domain == null)
                    return "";
                
                return _newAnecdote.Domain.ToString(); 
            }

            set
            {
                if (value == "")
                {
                    _newAnecdote.Domain = null;
                }
                else
                {
                    Domain existingDomain = null;
                    Boolean existingDomainFound = false;
                    foreach (Domain domain in Domains)
                    {
                        if (domain.Name == value)
                        {
                            existingDomainFound = true;
                            existingDomain = domain;
                        }
                    }

                    if (existingDomainFound)
                    {
                        _newAnecdote.Domain = existingDomain;
                    }
                    else
                    {
                        _newAnecdote.Domain = new Domain() { Name = value };
                    }
                }
                NotifyOfPropertyChange(() => CanAddNewAnecdote);
            }
        }

        public string NewAnecdoteNote
        {
            get
            {
                if (_newAnecdote.Note == null)
                {
                    return "";
                }
                else
                {
                    return _newAnecdote.Note;
                }
            }

            set
            {
                if (value == "")
                {
                    _newAnecdote.Note = null;
                }
                else
                {
                    _newAnecdote.Note = value;
                }
                NotifyOfPropertyChange(() => CanAddNewAnecdote);
            }
        }

        public string NewAnecdoteStudent
        {
            get 
            {
                if (_newAnecdote.Student == null)
                    return "";
                
                return _newAnecdote.Student.ToString(); 
            }

            set
            {
                if (value == "")
                {
                    _newAnecdote.Student = null;
                }
                else
                {
                    Student existingStudent = null;
                    Boolean existingStudentFound = false;
                    foreach (Student student in Students)
                    {
                        if (student.Name == value)
                        {
                            existingStudentFound = true;
                            existingStudent = student;
                        }
                    }

                    if (existingStudentFound)
                    {
                        _newAnecdote.Student = existingStudent;
                    }
                    else
                    {
                        _newAnecdote.Student = new Student() { Name = value };
                    }
                }
                NotifyOfPropertyChange(() => CanAddNewAnecdote);
            }
        }

        public AnecdotesViewModel(Presentation.Interfaces.IReadWriteModels models)
        {
            if (models == null)
            {
                models = new PresentationModels(null);
            }

                _modelsReader = models;
                _modelsWriter = models;

                _newAnecdote = new Anecdote();

                _modelsReader.AnecdotesChanged += OnAnecdoteChanged;
        }

        public bool CanAddNewAnecdote
        {
            get { return (_newAnecdote.Note != null && _newAnecdote.Domain != null && _newAnecdote.Student != null); }
        }

        public void AddNewAnecdote()
        {
            if (CanAddNewAnecdote)
            {
                _modelsWriter.AddAnecdote(_newAnecdote);
            }

            _newAnecdote.Date = DateTime.Now;

            _newAnecdote = new Anecdote(_newAnecdote); 
        }

        public void OnAnecdoteChanged(object sender, EventArgs e)
        {
            NotifyOfPropertyChange(() => UniqueNotes);
            NotifyOfPropertyChange(() => Domains);
            NotifyOfPropertyChange(() => Students);
            NotifyOfPropertyChange(() => Anecdotes);
        }

        public void RemoveAnecdote(Anecdote a)
        {
            _modelsWriter.RemoveAnecdote(a);
        }

    }
}
